package org.turl.utils;

import org.turl.objects.ComplexNumber;
import org.turl.objects.Angle;
import org.turl.objects.RectangularComplexNumber;
import org.turl.objects.PolarComplexNumber;
import org.turl.wrappers.WrapperToObject;
import org.turl.annotations.instanceConverter;

import java.lang.reflect.Constructor;

/**
 * Created by tonyx
 * Date: Dec 30, 2007
 * Time: 10:27:02 AM
 */
public class ComplexNumbersFactory {
    public final static String RECTANGULAR ="Rectangular";
    public final static String POLAR="Polar";
    private static String implementation=RECTANGULAR;

    public static void setImplementation(String anImplementation)
    {
        if (RECTANGULAR.equals(anImplementation)) {
            implementation=anImplementation;
        }
        if (POLAR.equals(anImplementation)) {
            implementation=anImplementation;
        }
    }

    public static String getImplementation()
    {
        return implementation;
    }


    public static ComplexNumber getComplexFromCartesianPar(double first ,double second)
    {
        if (RECTANGULAR.equals(implementation))
        {
            return new RectangularComplexNumber(first,second);
        }

        if (POLAR.equals(implementation))
        {

            ComplexNumber converted = (ComplexNumber) getInstanceOfThisActualGivenConstructorOfOther(PolarComplexNumber.class,RectangularComplexNumber.class, new Object[]{first,second},new Class[]{double.class,double.class},new Class[]{double.class, Angle.class});
            return converted;
        }
        throw new RuntimeException("unadmitted implementation mode "+implementation);
    }

    public static Object getInstanceOfThisActualGivenConstructorOfOther(Class targetClass, Class originClass, Object[] instanceOriginCompatible, Class[] instanceOriginClasses, Class[] instTargetClass) {
        try {
            Constructor constructor = originClass.getConstructor(instanceOriginClasses);
            WrapperToObject wrapper = (WrapperToObject) constructor.getAnnotation(instanceConverter.class).instanceConverterMap().newInstance();
            Object[] convertedPars = ((wrapper.getWrapperForClassConstructorWithParameters(targetClass, instTargetClass,instanceOriginClasses).wrap(instanceOriginCompatible)));
            Constructor targetConstructor = targetClass.getConstructor(instTargetClass);
            Object convertedObject = targetConstructor.newInstance(convertedPars);
            return convertedObject;

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
